package cn.mw.cmdb.view;

import cn.mw.cmdb.entity.*;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.components.mongodb.entity.SearchParam;
import cn.mw.components.mongodb.page.MWPage;
import cn.mw.microMonitorCommon.api.cmdb.TableIdEnum;
import cn.mw.microMonitorCommon.api.cmdb.TreeView;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Strings;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ViewManager implements InitializingBean {
    public static final String viewType = "exportView";
    private Map<Class, Class> viewFactory = new HashMap<>();

    public Object getViewObject(Object obj, ViewConvertContext context) throws Exception {
        ViewConvert viewConvert = genViewConvert(obj.getClass());
        if (context != null) {
            context.setParamData(obj);
            viewConvert.init(context);
        }
        return viewConvert.convert(obj, context);
    }

    /*
     * 实例具体的转换器类,并转换
     * obj: 需要被转换的对象
     * clazz: 转换器类
     */
    public Object getViewObject(Object obj, Class clazz, ViewConvertContext context) throws Exception {
        ViewConvert viewConvert = (ViewConvert) clazz.getDeclaredConstructor().newInstance();
        ;
        if (context != null) {
            context.setParamData(obj);
            viewConvert.init(context);
        }
        return viewConvert.convert(obj, context);
    }

    public Object getTreeViewObject(List<TreeView> list, ViewConvertContext context) throws Exception {
        ViewConvert viewConvert = genViewConvert(TreeView.class);
        if (null != context) {
            viewConvert.init(context);
        }

        return viewConvert.convert(list, context);
    }

    public <T> Object getListViewObject(List<T> list, Class clazz
            , SearchParam searchParam, ViewConvertContext context) throws Exception {

        ViewConvert viewConvert = genViewConvert(clazz);

        List ret = new ArrayList();
        if (null != viewConvert) {
            if (null != context) {
                viewConvert.init(context);
            }

            if (null != list) {
                for (T data : list) {
                    Object obj = viewConvert.convert(data, context);
                    ret.add(obj);
                }
            }
            //排序
            if (searchParam != null && !Strings.isNullOrEmpty(searchParam.getSortName())) {
                viewConvert.sortList(ret, searchParam, context);
            }
            viewConvert.finish(context, ret);
        } else if (null != list) {
            ret = list;
        }

        if (null != searchParam && null != searchParam.getPage()) {
            MWPage mwPage = searchParam.getPage();
            //如果没有设置总数,说明list的大小为总数
            if (mwPage.getTotal() < 0) {
                int count = (int) ret.size();
                mwPage.setTotal(count);
                int start = (int) CMDBTool.getPageStart(mwPage.getCurrent(), mwPage.getSize());
                int end = start + mwPage.getSize();
                if (end > count) {
                    end = count;
                }
                ret = ret.subList(start, end);
            }

            mwPage.setRecords(ret);
            return mwPage;
        }
        return ret;
    }

    public static <T> IPage<T> listToPage(List<T> list, long currentPage, long pageSize) {
        Page<T> page = new Page<>(currentPage, pageSize);
        page.setRecords(list);
        page.setTotal(list.size());
        return page;
    }

    public static Page listToPage(List realDatas,Integer pageNum,Integer pageSize){
        if(org.apache.commons.collections.CollectionUtils.isNotEmpty(realDatas)){
            int fromIndex = pageSize * (pageNum -1);
            int toIndex = pageSize * pageNum;
            if(toIndex > realDatas.size()){
                toIndex = realDatas.size();
            }
            List<Map<String,Object>> pageList = realDatas.subList(fromIndex, toIndex);
            Page page = new Page();
            page.setRecords(pageList);
            page.setTotal(realDatas.size());
            page.setSize(pageSize);
            return page;
        }
        return new Page();
    }


    private ViewConvert genViewConvert(Class clazz) throws Exception {
        Class viewConvertClass = viewFactory.get(clazz);
        if (null == viewConvertClass) {
            return null;
        }
        ViewConvert viewConvert = (ViewConvert) viewConvertClass.getDeclaredConstructor().newInstance();
        return viewConvert;
    }

    public void sortList(List data, SearchParam searchParam) {
        if (CollectionUtils.isNotEmpty(data)) {
            for (Object obj : data) {
                if (obj instanceof Map) {
                    Map map = (Map) obj;


                } else {

                }
            }

        }

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        viewFactory.put(ModelInfo.class, ModelTableConverter.class);
        viewFactory.put(InstanceInfo.class, InstanceInfoAuthViewConverter.class);
        viewFactory.put(TreeView.class, TreeViewConverter.class);
        viewFactory.put(ModelTemplateInfo.class, TemplateTableConverter.class);
        viewFactory.put(ModelSpecificationInfo.class, SortTableListConverter.class);
        viewFactory.put(MwMacOuiInfo.class, SortTableListConverter.class);
        viewFactory.put(ModelPropertyCatolog.class, ModelPropertyCatologConverter.class);
        viewFactory.put(InstanceInpuFieldsView.class, InstanceInpuFieldsViewConverter.class);
        viewFactory.put(TableIdEnum.class, TableDropdownConverter.class);
        viewFactory.put(InstanceRelationInfo.class, InstanceListViewConverter.class);
        viewFactory.put(AssetsScanResultInfo.class ,AssetsScanResultInfoConverter.class);
        viewFactory.put(AssetsScanTotalResultInfoVo.class ,AssetsScanTotalResultConverter.class);
    }
}
